package com.dl.chat.controller;

import com.dl.chat.client.VectorizationClient;
import com.dl.chat.entity.ChatHistory;
import com.dl.chat.entity.ChatRequest;
import com.dl.chat.service.ChatHistoryService;
import com.dl.chat.service.RedisService;
import com.dl.chat.service.VectorDatabaseService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;

@RestController
@RequestMapping("/ai")
public class ChatController {

    private static final Logger log = LoggerFactory.getLogger(ChatController.class);
    @Autowired
    ChatClient chatClient;

    @Autowired
    VectorDatabaseService vectorDatabaseService;
    @Autowired
    VectorizationClient vectorizationClient;

    @Autowired
    private RedisService redisService;

    @Autowired
    private ChatHistoryService chatHistoryService;

    /**
     * 正常的AI问答
     * @param request
     * @return
     */
    @PostMapping("/chat")
    public String chat(@RequestBody ChatRequest request) {

        String userId = request.getUserId();
        String question = request.getQuestion();

        log.info("userId:{},question:{}",userId,question);




        log.info("开始问题向量化");
        //0.将问题向量化
        float[] vectorizeText = vectorizationClient.vectorizeText(question);
        log.info("问题向量化成功");
        //0.1根据向量搜索最相似的文档
        List<String> search = vectorDatabaseService.search(vectorizeText, 1,0.8f);
        log.info("搜索到最相似的文档");
        // 1. 从 Redis 获取对话历史
        List<Map<String, String>> history = redisService.getChatHistory(userId);

        //2.构建提示词上下文
        String context = buildKnowledgeContext(search,question,history);
        log.info("构建提示词上下文：{}",context);

        log.info("开始问答");
        //1.询问AI大模型
        String content = chatClient.prompt(context).user(question).call().content();


        // 2. 处理问题和生成回答（省略具体逻辑）
        String answer = content;
        log.info("AI大模型回答：{}",answer);
        // 3. 将新对话保存到 Redis
        history.add(Map.of("role", "user", "content", question));
        history.add(Map.of("role", "assistant", "content", answer));
        redisService.saveChatHistory(userId, history);

        // 4. 将新对话持久化到 PostgreSQL
        ChatHistory userMessage = new ChatHistory();
        userMessage.setUserId(userId);
        userMessage.setRole("user");
        userMessage.setContent(question);
        userMessage.setCreatedAt(LocalDateTime.now());
        chatHistoryService.saveChatHistory(userMessage);

        ChatHistory assistantMessage = new ChatHistory();
        assistantMessage.setUserId(userId);
        assistantMessage.setRole("assistant");
        assistantMessage.setContent(answer);
        assistantMessage.setCreatedAt(LocalDateTime.now());
        chatHistoryService.saveChatHistory(assistantMessage);
        log.info("问答结束————————————————————————————");
        return answer;
    }

    /**
     * 构建知识上下文
     * @param search
     * @param question
     * @param history
     * @return
     */
    private String buildKnowledgeContext(List<String> search, String question, List<Map<String, String>> history) {
        StringBuilder context = new StringBuilder();
        for (String s : search) {
            context.append(s).append("\n");
        }
        for (Map<String, String> map : history) {
            context.append(map.get("role")).append(":").append(map.get("content")).append("\n");
        }
        context.append(question);
        return context.toString();
    }


    /**
     * 流式响应的接口
     * @param request
     * @return
     */
    @PostMapping(value = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter sse(@RequestBody ChatRequest request) {
        String userId = request.getUserId();
        String question = request.getQuestion();
        log.info("用户ID: {}, 问题: {}", userId, question);

        // 创建SSE发射器，设置60秒超时
        SseEmitter emitter = new SseEmitter(60_000L);

        // 使用AtomicBoolean跟踪状态
        AtomicBoolean isCompleted = new AtomicBoolean(false);

        // 添加事件处理器
        emitter.onCompletion(() -> {
            isCompleted.set(true);
            log.info("SSE连接正常完成");
        });
        emitter.onTimeout(() -> {
            isCompleted.set(true);
            log.warn("SSE连接超时");
        });
        emitter.onError(ex -> {
            isCompleted.set(true);
            log.error("SSE连接错误", ex);
        });

        // 使用线程池处理异步任务
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.execute(() -> {
            try {
                // 1. 向量化处理问题
                log.info("开始问题向量化处理...");
                float[] questionVector = vectorizationClient.vectorizeText(question);
                log.info("问题向量化完成");

                // 2. 向量数据库搜索
                List<String> relatedDocs = vectorDatabaseService.search(questionVector, 1,0.8f);
                log.info("找到{}条相关文档", relatedDocs.size());

                // 3. 获取历史对话
                List<Map<String, String>> chatHistory = redisService.getChatHistory(userId);

                // 4. 构建知识上下文
                String context = buildKnowledgeContext(relatedDocs, question, chatHistory);
                log.debug("构建的上下文: {}", context);

                // 5. 流式调用AI模型
                StringBuilder fullResponse = new StringBuilder();
                CountDownLatch completionLatch = new CountDownLatch(1);

                chatClient.prompt(context)
                        .user(question)
                        .stream()
                        .content()
                        .subscribe(
                                chunk -> {
                                    if (isCompleted.get()) {
                                        log.warn("Emitter已关闭，忽略后续数据块");
                                        return;
                                    }
                                    try {
                                        emitter.send(SseEmitter.event()
                                                .data(chunk)
                                                .id(UUID.randomUUID().toString()));
                                        fullResponse.append(chunk);
                                    } catch (IOException e) {
                                        log.error("发送数据块失败", e);
                                        if (!isCompleted.get()) {
                                            emitter.completeWithError(e);
                                        }
                                    }
                                },
                                error -> {
                                    log.error("流式处理出错", error);
                                    if (!isCompleted.get()) {
                                        emitter.completeWithError(error);
                                    }
                                    completionLatch.countDown();
                                },
                                () -> {
                                    log.info("流式处理完成");
                                    if (!isCompleted.get()) {
                                        // 保存完整记录
                                        saveCompleteConversation(userId, question, fullResponse.toString());
                                        emitter.complete();
                                    }
                                    completionLatch.countDown();
                                }
                        );

                // 等待流处理完成
                completionLatch.await();

            } catch (Exception e) {
                log.error("处理请求时出错", e);
                if (!isCompleted.get()) {
                    emitter.completeWithError(e);
                }
            } finally {
                executor.shutdown();
            }
        });

        return emitter;
    }
    /**
     * 保存完整对话记录的方法
      */

    private void saveCompleteConversation(String userId, String question, String answer) {
        try {
            // 1. 更新Redis中的聊天历史
            List<Map<String, String>> history = redisService.getChatHistory(userId);
            history.add(Map.of("role", "user", "content", question));
            history.add(Map.of("role", "assistant", "content", answer));
            redisService.saveChatHistory(userId, history);

            // 2. 持久化到PostgreSQL
            LocalDateTime now = LocalDateTime.now();

            ChatHistory userMessage = new ChatHistory();
            userMessage.setUserId(userId);
            userMessage.setRole("user");
            userMessage.setContent(question);
            userMessage.setCreatedAt(now);
            chatHistoryService.saveChatHistory(userMessage);

            ChatHistory assistantMessage = new ChatHistory();
            assistantMessage.setUserId(userId);
            assistantMessage.setRole("assistant");
            assistantMessage.setContent(answer);
            assistantMessage.setCreatedAt(now);
            chatHistoryService.saveChatHistory(assistantMessage);

            log.info("对话记录保存完成");
        } catch (Exception e) {
            log.error("保存对话记录时出错", e);
        }
    }


    /**
     * 从Redis中获取对话历史
     */
    @GetMapping("/gethistoryList")
    public List<Map<String, String>> getChatHistory( String userId) {
        System.out.println(userId);
        return redisService.getChatHistory(userId);
    }

}